package ns.gflex.services

import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import ns.gflex.orm.GForm;

import org.codehaus.groovy.grails.web.servlet.mvc.GrailsHttpSession;
import org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequest;
import org.springframework.web.context.request.RequestContextHolder;

import org.hibernate.NonUniqueObjectException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.criterion.Projections;

import flex.messaging.FlexContext;
import flex.messaging.FlexSession;
import grails.orm.HibernateCriteriaBuilder;
import grails.util.Environment;
import groovy.sql.Sql;

/**
 * service基础类
 * 创建时间 2010-6-1
 * @author wangchu
 */
abstract class GFlexService{
	SessionFactory sessionFactory
	static expose = ['flex-remoting']
	boolean transactional = true
	static final String SESSION_ACCOUNT_ID='AccountInFlexSession'

	protected Session getHibernateSession(){
		sessionFactory.currentSession
	}

	protected def getFlexSession(){
		//不是flex发起的request无法获取这个session
		//FlexContext.flexSession
		httpSession
	}

	/*protected HttpServletRequest getHttpRequest(){
	 FlexContext.httpRequest
	 }*/

	protected HttpServletRequest getHttpRequest(){
		GrailsWebRequest req = RequestContextHolder.currentRequestAttributes()
		req.request
	}

	protected HttpSession getHttpSession(){
		httpRequest.session
	}

	protected void logHost(String message,boolean isDebug=false){
		String host = httpRequest?httpRequest.remoteHost:'@server'
		if(isDebug)
			log.debug("$host $message")
		else
			log.info("$host $message")
	}

	void heartBeat(){
		logHost("send heart beat!",true)
	}
	/**
	 * 得到groovy sql 实例
	 * @return
	 */
	protected Sql getGroovySql(){
		new Sql(sessionFactory.currentSession.connection())
	}

	def save(Map map,boolean isMerge = false,Object domain=null){
		GForm.save map, isMerge ,forDomain(domain)
	}

	public List listEnabled(Map param=null, Object domain=null){
		log.info "listEnabled param:$param"
		if(param){
			if(param.eq)
				param.eq=param.eq.toList()<<['enabled', true]
			else
				param.eq=[['enabled', true]]
		}
		else
			param=[eq:[['enabled', true]]]
		list(param,domain)
	}

	/**
	 * @see GForm.list  
	 */
	List list(Map param=null,Object domain=null) {
		GForm.list param, forDomain(domain)
	}

	/**
	 * @see GForm.count
	 */
	int count(Map param=null,Object domain=null) {
		GForm.count param, forDomain(domain)
	}

	/**
	 * @param param ex.[projections:[countDistinct:[['customerId', 'countDistinct']]]]
	 * @param domain
	 * @return
	 */
	int countDistinct(Map param,Object domain){
		list(param, domain)[0].countDistinct;
	}

	/**
	 * @see GForm.saving
	 */
	protected def saving(def entity,boolean isMerge = false){
		GForm.saving(entity,isMerge)
	}

	/**
	 * 根据id删除关联信息
	 * @entityArray 包含id属性的实体列表 
	 */
	void deleteByIds(List idList,Object domain=null) {
		if(idList){
			deleteByNumberList(idList,'id',domain)
		}
	}

	void deleteByStringList(List valueList,String field,Object domain=null) {
		GForm.deleteByStringList(valueList,field,forDomain(domain))
	}

	void deleteByNumberList(List valueList,String field,Object domain=null) {
		GForm.deleteByNumberList(valueList,field,forDomain(domain))
	}

	/**
	 * 默认的实体类
	 * @return
	 */
	protected Class  getDomainClass(){
		return null
	}

	protected Object forDomain(Object domain){
		domain ?: getDomainClass()
	}


	/**当前登录工号
	 * @return
	 */
	String getSessionAccount(def session=null){
		/*if(Environment.isDevelopmentMode())
		 'admin'
		 else*/
		(session?:httpSession).getAttribute(SESSION_ACCOUNT_ID)
	}

	//某些工程没有ns.gflex.domain.User类，不能调用本方法
	def getSessionUser(){
		//防止编译错误
		if(sessionAccount)
			GForm.forDomain('ns.gflex.domain.User').findByAccount(sessionAccount)
	}

	/**
	 * 抛出RuntimeException异常
	 * @param str
	 * @return
	 */
	protected throwError(String str){
		throw new RuntimeException(str)
	}
}
